package com.panda.web.controller.commons;


import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.Color;
import com.itextpdf.kernel.colors.DeviceGray;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.canvas.draw.DashedLine;
import com.itextpdf.kernel.pdf.canvas.draw.DottedLine;
import com.itextpdf.kernel.pdf.canvas.draw.SolidLine;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.borders.DashedBorder;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.layout.property.VerticalAlignment;
import com.panda.common.core.domain.R;
import com.panda.web.domain.dto.OpenidUrl;
import com.panda.web.entity.commons.ServerFile;
import com.panda.web.entity.commons.WechatPicture;
import com.panda.web.entity.commons.WechatResume;
import com.panda.web.entity.product.OpenidProduct;
import com.panda.web.entity.wechatinfo.*;
import com.panda.web.mapper.commons.ServerFileMapper;
import com.panda.web.mapper.commons.WechatPictureMapper;
import com.panda.web.mapper.commons.WechatResumeMapper;
import com.panda.web.mapper.product.OpenidProductMapper;
import com.panda.web.mapper.wechatinfo.*;
import com.panda.web.utils.AAAUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.RequestBody;
//import org.json.JSONException;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
//import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.apache.fop.fonts.type1.AdobeStandardEncoding.bullet;
import static org.apache.fop.fonts.type1.AdobeStandardEncoding.o;

@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/kouzi")
public class KouZiController {//
    // 中文字体路径（需自行准备或使用系统字体）
    @Value("${file.upload-resume}")
    private String uploadResume; //简历上传

    @Value("${file.save-resume}")
    private String saveResume; //简历生成存储地址
    @Value("${file.save-picture}")
    private String savePicture; //简历生成存储地址


    @Value("${kouzi.api.apiUrl}")
    private String apiUrlApi; // api路径
    @Value("${kouzi.api.authToken}")
    private String authTokenApi; // token
    @Value("${kouzi.api.workflowId}")
    private String workflowIdApi; // 工作流id
    @Autowired
    WechatPictureMapper pictureMapper;
    @Autowired
    OpenidProductMapper openidProductMapper;

    @Autowired
    private WechatResumeMapper resumeMapper;//简历
    @Autowired
    private WechatUserinfoMapper userinfoMapper;
    @Autowired
    private UserSkillMapper skillMapper;//技能证书
    @Autowired
    private UserDemandMapper demandMapper;//求职地点
    @Autowired
    private UserHonorMapper userHonorMapper;
    @Autowired
    private UserProjectMapper userProjectMapper;//实习经历
    @Autowired
    private UserSchoolgoMapper userSchoolgoMapper;//校园实践经历

    @Autowired
    private UserEducationMapper userEducationMapper;//教育经历
    private static final String FONT_PATH = "/www/wwwroot/comments/Fonts/msyh.ttf";//微软雅黑
//    private static final String FONT_PATH = "/www/wwwroot/comments/Fonts/simhei.ttf";//黑体

    /**
     * 根据openid 获取个人上传的简历
     *
     * @param openid
     * @return
     */
    @GetMapping("/resume/{openid}")
    public R getResumeList(@PathVariable String openid) {
        List<WechatResume> resumeList = resumeMapper.findByOpenid(openid);
        return R.ok(resumeList, 200, "ok");
    }

    /**
     * 根据openid 获取个人上传的图片
     *
     * @param openid
     * @return
     */
    @GetMapping("/picture/{openid}")
    public R getPictureList(@PathVariable String openid) {
        WechatPicture picture = pictureMapper.findByOpenid(openid);
        return R.ok(picture, 200, "ok");
    }

    /**
     * 删除个人照片
     *
     * @param
     * @return
     * @throws IOException
     */
    @DeleteMapping("/pic/{openid}")
    public R deletedByPictureList(@PathVariable String openid) {

        return R.ok(pictureMapper.deleteByOpenid(openid), 200, "ok");
    }

    @Async
    @Transactional
    @PostMapping("/kouzi-resume")
    public R uploadResume(@org.springframework.web.bind.annotation.RequestBody OpenidUrl openidUrl) throws IOException {

        String openid = openidUrl.getOpenid();
        String url = openidUrl.getUrl();
        log.info(FONT_PATH + "font");

        List<OpenidProduct> productList = openidProductMapper.findOpenidByPuroduct(openid, "0");
        if (productList.size() > 0 && !productList.isEmpty()) {

            // 使用 stream API 获取 productId 最大的 OpenidProduct 对象
            OpenidProduct maxProduct = productList.stream()
                    .max(Comparator.comparingLong(OpenidProduct::getProductId))
                    .orElse(null); // 如果列表为空，返回 null

            if (maxProduct.getProductId() < 2 || maxProduct.getProductId() == 5) {
                throw new RemoteException("权限不足");
            } else if (maxProduct.getProductId() == 6) {
                if (maxProduct.getAiCount() - 1 >= 0) {
                    maxProduct.setAiCount(maxProduct.getAiCount() - 1);
                    maxProduct.setStatus("1");
                    openidProductMapper.updateById(maxProduct);
                } else {
                    throw new RemoteException("AI定制次数不足");
                }
            } else {
                if (maxProduct.getAiCount() - 1 >= 0) {
                    maxProduct.setAiCount(maxProduct.getAiCount() - 1);
                    openidProductMapper.updateById(maxProduct);
                } else {
                    throw new RemoteException("AI定制次数不足");
                }
            }

        } else {
            throw new RemoteException("未开通产品功能");
        }
        try {
            if (Objects.equals(url, null)) {
                log.info(url + ":{}" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaa");
                log.info(openid + ":{}" + "bbbbbbbbbbbbbbbbbbbb");
                throw new RemoteException("url为空");
            }
            String content = "需要根据提供的所有内容进行简历整合优化,这是个人其他信息:";
            content = getContent(openid, content);
//            String newContent = formatContent(content);

            // 1. 定义接口地址和认证信息
            String apiUrl = apiUrlApi; // 调取API Url
            String authToken = authTokenApi; // token
            String workflowId = workflowIdApi; // 工作流 ID
            String jsonBody = buildRequestBody(url, content, workflowId);
            log.info("{}: {}", content, "其他信息");
            log.info("{}: {}", jsonBody, "JSON请求体");
            // 3. 创建 OkHttpClient 客户端
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(150, TimeUnit.SECONDS)  // 连接超时，设置为120秒
                    .readTimeout(150, TimeUnit.SECONDS)     // 读取超时，设置为120秒
                    .writeTimeout(150, TimeUnit.SECONDS)    // 写入超时，设置为120秒
                    .build();

            // 4. 创建请求体，指定 Content-Type 为 application/json
            RequestBody requestBody = RequestBody.create(
                    MediaType.parse("application/json"), jsonBody);
// 5. 创建请求
            Request request = new Request.Builder()
                    .url(apiUrl)
                    .post(requestBody)
                    .addHeader("Authorization", "Bearer " + authToken)
                    .build();
            String resumeContent = null;
            try {
                // 1. 发送请求并获取响应
                Response response = client.newCall(request).execute();
                if (!response.isSuccessful()) {
                    throw new IOException("请求失败: " + response.code());
                }
                String responseBody = response.body().string(); // 2. 读取响应内容（注意：response.body().string() 只能调用一次）
                log.debug("原始响应内容: {}", responseBody);
                JsonObject root = JsonParser.parseString(responseBody).getAsJsonObject();// 3. 使用 Gson 解析外层 JSON
                String dataStr = root.get("data").getAsString();// 4. 提取 data 字段（此时 data 是字符串形式的 JSON）
                JsonObject dataObj = JsonParser.parseString(dataStr).getAsJsonObject();   // 5. 二次解析 data 字段中的 JSON

                // 6. 获取最终内容
                resumeContent = dataObj.get("output").getAsString();
                log.info("解析成功，简历内容: \n{}", resumeContent);

            } catch (JsonSyntaxException e) {
                log.error("JSON 语法错误，请检查响应格式: {}", e.getMessage());
                throw new RuntimeException("响应格式不符合预期");
            } catch (IllegalStateException e) {
                log.error("JSON 结构错误，字段缺失: {}", e.getMessage());
                throw new RuntimeException("响应缺少必要字段");
            } catch (IOException e) {
                log.error("网络或 IO 错误: {}", e.getMessage());
                throw new RuntimeException("请求处理失败");
            }
            String uuid = UUID.randomUUID().toString();
            // 构建文件的目标路径，例如: uploads/2024-12-13/文件名
            String outputPath = saveResume + "/" + uuid + ".pdf";
            String picture = null;
            WechatPicture wechatPicture = pictureMapper.findByOpenid(openid);
            if (wechatPicture == null) {
                System.out.println("没有个人照片");
                picture = "https://houtaiguanli.yanbeibao2021.com/file/document/58256.png";//替换为个人头像
            } else {
                picture = wechatPicture.getUrl();
            }

            String filePath = generatePdf(resumeContent, outputPath, picture);//存储文件路径
            String domainName = "https://houtaiguanli.yanbeibao2021.com"; // 当前域名
            // 服务器根路径，排除的部分
            String rootDir = "/www/wwwroot/houtaiguanli.yanbeibao2021.com/dist";
            // 将文件路径中的根目录部分替换为空，获取相对路径
            String relativePath = filePath.replace(rootDir, "");
            // 拼接成前端可访问的 URL
            String path = domainName + relativePath;//拼接后路径
            Map<String, String> stringMap = new HashMap<>();
            stringMap.put("url", path);
            stringMap.put("code", "200");
            stringMap.put("url", path);
            return R.ok(path, 200, "ok");
        } catch (IOException e) {
            e.printStackTrace();
            return R.ok(e.getMessage(), 500, "error");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public String buildRequestBody(String url, String content, String workflowId) throws Exception {
        Map<String, Object> requestBody = new HashMap<>();
        Map<String, String> parameters = new HashMap<>();
        parameters.put("url", url);
        parameters.put("content", content);
        requestBody.put("parameters", parameters);
        requestBody.put("workflow_id", workflowId);
        return new ObjectMapper().writeValueAsString(requestBody);
    }
    public static String formatContent(String content) {
        if (content == null) {
            return "";
        }

        // 转义双引号和反斜杠
        content = content.replace("\\", "\\\\"); // 处理反斜杠
        content = content.replace("\"", "\\\""); // 处理双引号

        // 可选的：处理换行符和回车符，具体需求根据是否需要
        content = content.replace("\n", "\\n");
        content = content.replace("\r", "\\r");

        return content;
    }
    private String getContent(String openid, String content) {


        WechatUserinfo userinfo = userinfoMapper.findByOpenid(openid);

        if (userinfo != null) {
            content = content + " 姓名：" + userinfo.getName() + ",性别：" + userinfo.getSex()+",年龄: "+userinfo.getAge() + ",民族：" + userinfo.getNation() + ",政治面貌：" + userinfo.getPolitics() ;//+ ",专业：" + userinfo.getMajor()
            if (userinfo.getEnglishFour() != null && userinfo.getEnglishFour().trim().equals("是")) {
                content = content + "，英语四级证书";
            }
            if (userinfo.getEnglishSix() != null && userinfo.getEnglishSix().trim().equals("是")) {
                content = content + "，英语六级证书";
            }
            if (userinfo.getComputerTwo() != null && userinfo.getComputerTwo().trim().equals("是")) {
                content = content + "，计算机二级证书";
            }
        }
        if (userinfo.getSelfEvaluation()!=null) {
            content = content + "个人评价：" + userinfo.getSelfEvaluation();
        }

        List<UserDemand> demandList = demandMapper.findByOpenid(openid);
        if (demandList != null && !demandList.isEmpty()) {
            String searchLocation = demandList.get(0).getSearchLocation();//求职地点
            String nativePlace = demandList.get(0).getNativePlace();//户籍地
            String jobIntention = demandList.get(0).getJobIntention();//户籍地
            //判断求职地点
            String topTwoJobIntentions = getTopTwoJobIntentions(searchLocation);

            content = content + ",求职地点：" + topTwoJobIntentions + ",户籍地：" + nativePlace;
            if (jobIntention != null) {
                content = content + ",求职意向：" + jobIntention;
            }

        }
        //教育经历
        List<UserEducation> userEducationList = userEducationMapper.findByOpenid(openid);
        if (userEducationList!=null&&!userEducationList.isEmpty()){
            content = content + ",教育经历：";
            int a =1;
            for (UserEducation education : userEducationList) {
                content = content+a+"、"+"毕业学校："+education.getSchool()+"，学位："+education.getDegree()+",专业:"+education.getMajor()+"，课程："+education.getCourse()+",毕业时间："+education.getTime()+";";
            }
        }
        List<UserProject> userProjectList = userProjectMapper.findByOpenid(openid);
        if (userProjectList != null && !userProjectList.isEmpty()) {
            content = content + ",实习经历：";
            int a =1;

            for (UserProject userProject : userProjectList) {
                if (!Objects.equals(userProject.getName(),null)&&!Objects.equals(userProject.getName(),"无")){
                    content = content +a+"、" + "名称：" + userProject.getName();
                }
                if (!Objects.equals(userProject.getStartingTime(),null)&&!Objects.equals(userProject.getStartingTime(),"无")){
                    content = content + ",起止时间：" + userProject.getStartingTime();
                }
                if (!Objects.equals(userProject.getDept(),null)&&!Objects.equals(userProject.getDept(),"无")){
                    content = content + ",部门：" + userProject.getDept();
                }
                if (!Objects.equals(userProject.getPost(),null)&&!Objects.equals(userProject.getPost(),"无")){
                    content = content + ",职位：" + userProject.getPost();
                }
                if (!Objects.equals(userProject.getContent(),null)&&!Objects.equals(userProject.getContent(),"无")){
                    content = content + ",内容：" + userProject.getContent();
                }
                if (!Objects.equals(userProject.getPerformance(),null)&&!Objects.equals(userProject.getPerformance(),"无")){
                    content = content + ",业绩：" + userProject.getPerformance();
                }
                if (!Objects.equals(userProject.getSelfEvaluation(),null)&&!Objects.equals(userProject.getSelfEvaluation(),"无")){
                    content = content + ",评价：" + userProject.getSelfEvaluation();
                }
            }
        }
        //校园实践
        List<UserSchoolgo> userSchoolgoList = userSchoolgoMapper.findByOpenid(openid);
        if (userSchoolgoList!=null&&!userSchoolgoList.isEmpty()){
            content = content + ",校园实践：";
            int a =1;
            for (UserSchoolgo userSchoolgo : userSchoolgoList) {
                if (!Objects.equals(userSchoolgo.getName(),null)&&!Objects.equals(userSchoolgo.getName(),"无")){
                    content = content+a+"、" + "名称：" + userSchoolgo.getName();
                }
                if (!Objects.equals(userSchoolgo.getDept(),null)&&!Objects.equals(userSchoolgo.getDept(),"无")){
                    content = content + ",部门：" + userSchoolgo.getDept();
                }
                if (!Objects.equals(userSchoolgo.getTime(),null)&&!Objects.equals(userSchoolgo.getTime(),"无")){
                    content = content + ",起止时间：" + userSchoolgo.getTime();
                }
                if (!Objects.equals(userSchoolgo.getPost(),null)&&!Objects.equals(userSchoolgo.getPost(),"无")){
                    content = content + ",职位：" + userSchoolgo.getPost();
                }
                if (!Objects.equals(userSchoolgo.getContent(),null)&&!Objects.equals(userSchoolgo.getContent(),"无")){
                    content = content + ",内容：" + userSchoolgo.getContent();
                }
                if (!Objects.equals(userSchoolgo.getScore(),null)&&!Objects.equals(userSchoolgo.getScore(),"无")){
                    content = content + ",成绩：" + userSchoolgo.getScore();
                }
                if (!Objects.equals(userSchoolgo.getSelfEvaluation(),null)&&!Objects.equals(userSchoolgo.getSelfEvaluation(),"无")){
                    content = content + ",评价：" + userSchoolgo.getSelfEvaluation();
                }
            }
        }
        //专业技能
        List<UserSkill> skillsList = skillMapper.findByOpenid(openid);
        if (skillsList != null && !skillsList.isEmpty()) {
//            String name = skillsList.get(0).getName();
//            content = content + "证书：" + name;
            content = content + "证书：" ;
            int a = 1;
            for (UserSkill userSkill : skillsList) {
                if (!Objects.equals(userSkill.getName(),null)){
                    content = content +a+"、" + ",名称：" + userSkill.getName();
                }
                if (!Objects.equals(userSkill.getBjjg(),null)){
                    content = content + ",颁奖机构：" + userSkill.getBjjg();
                }
            }
        }
        //荣誉奖励
        List<UserHonor> userHonorList = userHonorMapper.findByOpenid(openid);
        if (userHonorList != null && !userHonorList.isEmpty()) {
            String a = null;
            int aa = 1;
            for (UserHonor userHonor : userHonorList) {
                a = a +aa+"、级别："+ userHonor.getRank() + ",证书：" + userHonor.getName()+";";
                aa = aa+1;
            }

            content = content + ",荣誉奖励：" + a;
        }
        return content;

    }

    public String getTopTwoJobIntentions(String jobIntention) {
        if (jobIntention == null || jobIntention.isEmpty()) {
            return "";  // 如果没有数据，返回空字符串
        }

        // 按照逗号分隔字符串，得到城市数组
        String[] cities = jobIntention.split(",");

        // 如果只有一个城市，直接返回该城市
        if (cities.length == 1) {
            return cities[0].trim();
        }

        // 否则，取前两个城市
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < Math.min(2, cities.length); i++) {
            if (i > 0) {
                result.append(",");  // 在城市名称之间加逗号
            }
            result.append(cities[i].trim());  // 去除城市名称两端的空格
        }

        return result.toString();  // 返回前两个城市名称
    }


//    新调整简历样式

    // 新增静态常量
    private static final Color TITLE_COLORA = new DeviceGray(0.2f);
    private static final String TITLE_ICON = "/www/wwwroot/comments/picture/tubiao2.png";//"标题图标路径（推荐12x12像素PNG）"
    //    private static final String TITLE_ICON = "C:/Users/Administrator/Desktop/常贝医药/tubiao2.png";//"标题图标路径（推荐12x12像素PNG）"
    private static final String BACKGROUND_PATH = "/www/wwwroot/comments/picture/50.png";
    //    private static final String FONT_PATH = ""; // 微软雅黑
    private static final Color TITLE_COLOR = new DeviceRgb(0.173f, 0.243f, 0.314f); // 2
    private static final Color CONTENT_COLOR = new DeviceRgb(0.2f, 0.2f, 0.2f); // 正文颜色
    private static final Color CONTENT_COLORA = new DeviceRgb(0.1f, 0.6f, 0.7f); // 正文颜色
    private static final float TITLE_UNDERLINE_WIDTH = 1.2f;
    private static final float PHOTO_WIDTH = 80f;
    private static final float PHOTO_HEIGHT = 100f;

    public static String generatePdf(String content, String outputPath, String picture) throws IOException {
        PdfWriter writer = new PdfWriter(outputPath);
        PdfDocument pdf = new PdfDocument(writer);
        Document document = new Document(pdf, PageSize.A4);
        document.setMargins(40, 40, 40, 40);

        // 设置全局字体
        PdfFont font = PdfFontFactory.createFont(FONT_PATH, PdfEncodings.IDENTITY_H, true);
        document.setFont(font);

        // 1. 提前加载并验证背景图片
        // 3. 注册背景处理事件（必须在添加内容前注册）
        ImageData backgroundImage = ImageDataFactory.create(BACKGROUND_PATH);
        pdf.addEventHandler(PdfDocumentEvent.START_PAGE, new KouZiController.BackgroundEventHandler(backgroundImage));


        // 解析内容
        String[] lines = content.split("\n");

        // 头部信息处理
        List<String> headerLines = new ArrayList<>();
        if (lines.length > 1) headerLines.add(processDynamicLine(lines[1]));
        if (lines.length > 2 && !lines[2].trim().isEmpty()) {
            headerLines.add(lines[2].trim());
        }

        // 头部表格布局
        Table headerTable = new Table(new float[]{70, 30})
                .useAllAvailableWidth()
                .setMarginTop(20)
                .setMarginBottom(10);

        // 左侧信息区
        Div infoContainer = new Div()
                .setTextAlignment(TextAlignment.CENTER)
                .setVerticalAlignment(VerticalAlignment.MIDDLE);

        // 姓名处理
        Paragraph namePara = new Paragraph(extractName(lines[0]))
                .setBold()
                .setFontSize(20)
                .setFontColor(TITLE_COLORA)
                .setMarginBottom(headerLines.isEmpty() ? 0 : 8);

        infoContainer.add(namePara);

        // 动态信息行
        for (String line : headerLines) {
            infoContainer.add(new Paragraph(line)
                    .setFontSize(12)
                    .setFontColor(CONTENT_COLOR)
                    .setMultipliedLeading(1.2f));
        }

        // 右侧照片区
        Image photo = new Image(ImageDataFactory.create(picture))
                .scaleToFit(PHOTO_WIDTH, PHOTO_HEIGHT);

        // 构建表格
        headerTable.addCell(new Cell()
                .setBorder(Border.NO_BORDER)
                .add(infoContainer)
                .setVerticalAlignment(VerticalAlignment.MIDDLE));

        headerTable.addCell(new Cell()
                .setBorder(Border.NO_BORDER)
                .setHorizontalAlignment(HorizontalAlignment.RIGHT)
                .add(photo));

        document.add(headerTable);

        // 内容模块处理
        Div currentModule = null;
        int moduleItemNumber = 1; // 模块级序号计数器

        for (int i = 3; i < lines.length; i++) {
            String line = lines[i].trim();

            if (line.startsWith("###")) {
                if (currentModule != null) document.add(currentModule);
                currentModule = new Div().setMarginTop(12);
                moduleItemNumber = 1; // 重置序号

                // 带图标的标题
                String title = line.substring(3).trim();
                Paragraph titlePara = new Paragraph()
                        .add(new Image(ImageDataFactory.create(TITLE_ICON))
                                .scaleToFit(15, 15))
                        .add(" " + title)
                        .setBold()
                        .setFontSize(16)
                        .setFontColor(TITLE_COLOR)
                        .setMarginBottom(3);
                currentModule.add(titlePara);
                // 标题下划线
// 将虚线间距设为0，模拟实线效果
                DottedLine AAAA = new DottedLine(TITLE_UNDERLINE_WIDTH); // 宽度参数化
                AAAA.setGap(0);                   // 消除虚线间距
                AAAA.setColor(TITLE_COLOR);        // 直接设置颜色（关键点）

                currentModule.add(
                        new LineSeparator(AAAA)
                                .setMarginTop(1)
                                .setMarginBottom(5)
                );
            } else if (!line.isEmpty()) {
                if (currentModule != null) {

                    // 带序号的内容处理
                    if (line.startsWith("- ")) {

                        String numberedText = moduleItemNumber++ + ". " + line.substring(2);
                        processListItem(currentModule, numberedText, font);
                    } else if (line.startsWith("**")) {
                        processContentLine(currentModule, line, font);
//                        processContentLine(currentModule, line, font,BOLD_ICON_PATH);
                    } else {
                        processContentLineA(currentModule, line, font);
                    }
                }
            }
        }
        if (currentModule != null) document.add(currentModule);

        document.close();
        return outputPath;
    }

    /**
     * 背景图片处理事件
     */
    private static class BackgroundEventHandler implements IEventHandler {
        private final ImageData backgroundImage;

        public BackgroundEventHandler(ImageData backgroundImage) {
            this.backgroundImage = backgroundImage;
        }

        @Override
        public void handleEvent(Event event) {
            PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
            PdfPage page = docEvent.getPage();
            Rectangle pageSize = page.getPageSize();

            // 创建底层画布（保证背景在内容下方）
            PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), docEvent.getDocument());

            // 计算缩放比例（覆盖整个页面）
            canvas.addImage(backgroundImage,
                    pageSize.getWidth(), 0,   // X轴缩放比例（宽度撑满）
                    0, pageSize.getHeight(),  // Y轴缩放比例（高度撑满）
                    0, 0                      // 从页面左下角开始绘制
            );

            canvas.release();
        }
    }

//    private static void processContentLineA(Div container, String text, PdfFont font) {
//        Paragraph para = new Paragraph()
//                .setFontColor(CONTENT_COLOR)
//                .setMarginBottom(8)
//                .setFixedLeading(14)
//                .setTextAlignment(TextAlignment.LEFT);
//
//        // 加粗文本处理
//        String[] parts = text.split("\\*\\*");
//        boolean isBold = false;
//        for (String part : parts) {
//            if (!part.isEmpty()) {
//                Text segment = new Text(part).setFont(font);
//                if (isBold) segment.setBold();
//                para.add(segment);
//            }
//            isBold = !isBold;
//        }
//        container.add(para);
//    }
//
//    private static void processContentLine(Div container, String text, PdfFont font) {
//        Paragraph para = new Paragraph()
//                .setFontColor(CONTENT_COLOR)
//                .setMarginBottom(8)
//                .setFixedLeading(14)
//                .setTextAlignment(TextAlignment.LEFT);
//
//        // 加粗文本处理
//        String[] parts = text.split("\\*\\*");
//        boolean isBold = false;
//        for (String part : parts) {
//            if (!part.isEmpty()) {
//                Text segment = new Text(part).setFont(font);
//                if (isBold) segment.setBold();
//                para.add(segment);
//            }
//            isBold = !isBold;
//        }
//        container.add(para);
//    }
// 修改后的processContentLine和processContentLineA
private static void processContentLine(Div container, String text, PdfFont font) {
    Paragraph para = new Paragraph()
            .setFontColor(CONTENT_COLOR)
            .setMarginBottom(8)
            .setFixedLeading(14)
            .setTextAlignment(TextAlignment.LEFT);
    addBoldProcessedText(para, text, font);
    container.add(para);
}

    private static void processContentLineA(Div container, String text, PdfFont font) {
        Paragraph para = new Paragraph()
                .setFontColor(CONTENT_COLOR)
                .setMarginBottom(8)
                .setFixedLeading(14)
                .setTextAlignment(TextAlignment.LEFT);
        addBoldProcessedText(para, text, font);
        container.add(para);
    }

//    private static void processListItem(Div container, String text, PdfFont font) {
////         1. 替换中文标点为带防换行空格的版本（\u00A0 是不可分割空格）
//        if (text.startsWith("- ")) {
//            processSubItem(container, text.substring(2), font);
//        } else if (text.startsWith("○ ")) {
//            processSubItem(container, text.substring(2), font);
//        } else if (text.startsWith("+ ")) {  // 添加对加号的处理
//            processSubItem(container, text.substring(2), font); // 你可以定义不同的方法来处理加号项
//        } else if (text.startsWith("* ")) { // 如果以 * 开头，去掉星号和空格
//            text = text.substring(2); // 删除星号和空格
////            processSubItem(container, text.substring(2), font);
//        } else {
//
//            try {
//                Image bullet = new Image(ImageDataFactory.create(""))
//                        .scaleToFit(8, 8);
//                Paragraph para = new Paragraph()
//                        .add(bullet)
//                        .add(" " + text)
//                        .setFontColor(CONTENT_COLOR)
//                        .setMarginLeft(15)
//                        .setFixedLeading(14);
//
//                container.add(para);
//            } catch (Exception e) {
//                // 图标加载失败时降级处理
//                Paragraph para = new Paragraph("" + text)
//                        .setFontColor(CONTENT_COLOR)
//                        .setMarginLeft(15)
//                        .setFixedLeading(14);
//                container.add(para);
//            }
//        }
//
//    }
// 修改后的processListItem方法
private static void processListItem(Div container, String text, PdfFont font) {
    if (text.startsWith("- ")) {
        processSubItem(container, text.substring(2), font);
    } else if (text.startsWith("○ ")) {
        processSubItem(container, text.substring(2), font);
    } else if (text.startsWith("+ ")) {
        processSubItem(container, text.substring(2), font);
    } else if (text.startsWith("* ")) {
        text = text.substring(2);
        processSubItem(container, text, font);
    } else {
        try {
            Image bullet = new Image(ImageDataFactory.create(""))
                    .scaleToFit(8, 8);
            Paragraph para = new Paragraph()
                    .add(bullet)
                    .setFontColor(CONTENT_COLOR)
                    .setMarginLeft(15)
                    .setFixedLeading(14);
            addBoldProcessedText(para, " " + text, font);
            container.add(para);
        } catch (Exception e) {
            Paragraph para = new Paragraph()
                    .setFontColor(CONTENT_COLOR)
                    .setMarginLeft(15)
                    .setFixedLeading(14);
            addBoldProcessedText(para, text, font);
            container.add(para);
        }
    }
}

    // 动态行处理逻辑
    private static String processDynamicLine(String rawLine) {
        String[] parts = rawLine.split("\\|");
        List<String> validParts = new ArrayList<>();

        // 有效字段筛选规则
        Set<String> skipPatterns = Set.of(
                "未提及性别",
                "未提及年龄",
                "未提及户籍地",
                "未提及政治面貌",
                "未提及民族"
        );

        for (String part : parts) {
            String trimmed = part.trim();
            if (!trimmed.isEmpty() && !skipPatterns.contains(trimmed)) {
                validParts.add(trimmed);
            }
        }
        return String.join(" | ", validParts);
    }

    // 增强内容处理方法
//    private void processContentLine(Div container, String text, PdfFont font) {
//        // 1. 替换中文标点为带防换行空格的版本（\u00A0 是不可分割空格）
//        if (text.startsWith("- ")) {
//            processListItem(container, text.substring(2), font);
//        } else if (text.startsWith("○ ")) {
//            processSubItem(container, text.substring(2), font);
//        } else if (text.startsWith("+ ")) {  // 添加对加号的处理
//            processSubItem(container, text.substring(2), font); // 你可以定义不同的方法来处理加号项
//        } else if (text.startsWith("* ")) { // 如果以 * 开头，去掉星号和空格
//            text = text.substring(2); // 删除星号和空格
//        }else {
//
//            // 处理普通文本段落
//            Paragraph para = new Paragraph();
//            processBoldText(para, text, font);
//            para.setMarginBottom(8)
//                    .setFixedLeading(14)  // 缩小行高到12磅（原14）
//                    .setTextAlignment(TextAlignment.LEFT)  // 新增：两端对齐
//                    .setMarginLeft(15);
//            container.add(para);
//        }
//    }

//    private void processListItem(Div container, String text, PdfFont font) {
//        Paragraph para = new Paragraph()
//                .setMarginLeft(15)
//                .setMarginBottom(8)
//                .setFixedLeading(14)  // 缩小行高
//                .setTextAlignment(TextAlignment.LEFT);  // 两端对齐
//
//
//        processBoldText(para, text, font); // 处理加粗文本
//
//        // 如果文本中包含加号，直接在段落中显示加号
//        if (text.contains("+")) {
//            Text plusText = new Text(" ").setFont(font);  // 加号文本
//            para.add(plusText);  // 将加号添加到段落
//        }else if (text.startsWith("* ")) { // 如果以 * 开头，去掉星号和空格
//            text = text.substring(2); // 删除星号和空格
//        }
//        container.add(para);
//    }

    private static void processSubItem(Div container, String text, PdfFont font) {
        Paragraph para = new Paragraph()
                .setMarginLeft(25)
                .setFixedLeading(14);
        addBoldProcessedText(para, text, font);
        container.add(para);
    }
    // 新增公共方法处理加粗文本
    private static void addBoldProcessedText(Paragraph para, String text, PdfFont font) {
        String[] parts = text.split("\\*\\*");
        boolean isBold = false;
        for (String part : parts) {
            if (!part.isEmpty()) {
                Text segment = new Text(part).setFont(font);
                if (isBold) segment.setBold();
                para.add(segment);
            }
            isBold = !isBold;
        }
    }
//    // 新增的辅助方法：解析加粗文本
//    private static void processBoldText(Paragraph para, String text, PdfFont font) {
//        // 按 ** 拆分文本
//        String[] parts = text.split("\\*\\*");
//        boolean isBold = false;
//        for (String part : parts) {
//            if (!part.isEmpty()) {
//                Text segment = new Text(part).setFont(font);
//                if (isBold) {
//                    segment.setBold(); // 将加粗文本应用到对应部分
//                }
//                para.add(segment);
//            }
//            isBold = !isBold;  // 每次切换加粗状态
//        }
//    }

    private static String extractName(String line) {
        return line.replaceAll("\\*", "").trim();
    }
//
//    //原简历样式
//    private static final Color TITLE_COLOR = new DeviceGray(0.2f);
//    private static final float TITLE_UNDERLINE_WIDTH = 1.2f;
//    private static final float PHOTO_WIDTH = 80f; // 标准化照片宽度
//    private static final float PHOTO_HEIGHT = 100f;
//    public String generatePdf(String content, String outputPath, String picture) throws IOException {
//
//
//        PdfWriter writer = new PdfWriter(outputPath);
//        PdfDocument pdf = new PdfDocument(writer);
//        Document document = new Document(pdf, PageSize.A4);
//        document.setMargins(40, 40, 40, 40);
//
//        // 设置全局黑体
//        PdfFont font = PdfFontFactory.createFont(FONT_PATH, PdfEncodings.IDENTITY_H, true);
//        document.setFont(font);
//
//        // 解析内容
//        String[] lines = content.split("\n");
//
//// 动态解析头部信息
//        List<String> headerLines = new ArrayList<>();
//
//        // 第1行处理（动态字段）
//        String line1 = processDynamicLine(lines.length > 1 ? lines[1] : "");
//        if (!line1.isEmpty()) headerLines.add(line1);
//
//        // 第2行处理（求职意向）
//        if (lines.length > 2 && !lines[2].trim().isEmpty()) {
//            String jobIntention = lines[2].trim();
//            headerLines.add(jobIntention);
//        }
//
//        // 创建弹性布局表格
//        Table headerTable = new Table(new float[]{70, 30})
//                .useAllAvailableWidth()
//                .setMarginTop(20)
//                .setMarginBottom(10);
//
//        // ==== 左侧信息区 ====
//        Div infoContainer = new Div()
//                .setTextAlignment(TextAlignment.CENTER)
//                .setVerticalAlignment(VerticalAlignment.MIDDLE);
//
//        // 姓名行（必选）
//        Paragraph namePara = new Paragraph(extractName(lines[0]))
//                .setBold()
//                .setFontSize(20)
//                .setMarginBottom(headerLines.isEmpty() ? 0 : 8);
//
//        infoContainer.add(namePara);
//
//        // 动态信息行处理
//        for (String line : headerLines) {
//            infoContainer.add(new Paragraph(line)
//                    .setFontSize(12)
//                    .setMultipliedLeading(1.2f));
//        }
//
//        Cell infoCell = new Cell()
//                .setBorder(Border.NO_BORDER)
//                .add(infoContainer)
//                .setVerticalAlignment(VerticalAlignment.MIDDLE);
//
//        // ==== 右侧照片区 ====
//        Image photo = new Image(ImageDataFactory.create(picture));
//        photo.scaleToFit(PHOTO_WIDTH, PHOTO_HEIGHT);
//
//        Cell photoCell = new Cell()
//                .setBorder(Border.NO_BORDER)
//                .setHorizontalAlignment(HorizontalAlignment.RIGHT)
//                .setVerticalAlignment(VerticalAlignment.MIDDLE)
//                .add(photo);
//
//        headerTable.addCell(infoCell);
//        headerTable.addCell(photoCell);
//        document.add(headerTable);
//
//
//        // ==== 内容模块 ====
//        Div currentModule = null;
//        boolean isFirstModule = true;
//
//        for (int i = 3; i < lines.length; i++) {
//            String line = lines[i].trim();
//
//            if (line.startsWith("###")) {
//                // 模块间距控制
//                if (currentModule != null) {
//                    document.add(currentModule);
//                }
//                currentModule = new Div().setMarginTop(12);
//
//                // 标题处理
//                String title = line.substring(3).trim();
//                Paragraph titlePara = new Paragraph(title)
//                        .setBold()
//                        .setFontSize(16)
//                        .setMarginBottom(3);
//
//                // 紧凑下划线
//                LineSeparator underline = new LineSeparator(new SolidLine(TITLE_UNDERLINE_WIDTH))
//                        .setStrokeColor(TITLE_COLOR)
//                        .setMarginTop(1)  // 缩小间距
//                        .setMarginBottom(5);
//
//                currentModule.add(titlePara);
//                currentModule.add(underline);
//                isFirstModule = false;
//            } else if (!line.isEmpty()) {
//                // 增加空指针检查
//                if (currentModule != null) {
//                    processContentLine(currentModule, line, font);
//                } else {
//                    // 处理游离内容（根据需求选择记录或忽略）
//                    System.out.println("[WARN] 发现模块外内容: " + line);
//                }
//            }
//        }
//        if (currentModule != null) document.add(currentModule);
//
//        document.close();
//        return outputPath;
//    }
//
//    // 动态行处理逻辑
//    private String processDynamicLine(String rawLine) {
//        String[] parts = rawLine.split("\\|");
//        List<String> validParts = new ArrayList<>();
//
//        // 有效字段筛选规则
//        Set<String> skipPatterns = Set.of(
//                "未提及性别",
//                "未提及年龄",
//                "未提及户籍地",
//                "未提及政治面貌",
//                "未提及民族"
//        );
//
//        for (String part : parts) {
//            String trimmed = part.trim();
//            if (!trimmed.isEmpty() && !skipPatterns.contains(trimmed)) {
//                validParts.add(trimmed);
//            }
//        }
//        return String.join(" | ", validParts);
//    }
//
//    // 增强内容处理方法
//    private void processContentLine(Div container, String text, PdfFont font) {
//        // 1. 替换中文标点为带防换行空格的版本（\u00A0 是不可分割空格）
//        if (text.startsWith("- ")) {
//            processListItem(container, text.substring(2), font);
//        } else if (text.startsWith("○ ")) {
//            processSubItem(container, text.substring(2), font);
//        } else if (text.startsWith("+ ")) {  // 添加对加号的处理
//            processSubItem(container, text.substring(2), font); // 你可以定义不同的方法来处理加号项
//        } else if (text.startsWith("* ")) { // 如果以 * 开头，去掉星号和空格
//            text = text.substring(2); // 删除星号和空格
//        }else {
//
//            // 处理普通文本段落
//            Paragraph para = new Paragraph();
//            processBoldText(para, text, font);
//            para.setMarginBottom(8)
//                    .setFixedLeading(14)  // 缩小行高到12磅（原14）
//                    .setTextAlignment(TextAlignment.LEFT)  // 新增：两端对齐
//                    .setMarginLeft(15);
//            container.add(para);
//        }
//    }
//
//    private void processListItem(Div container, String text, PdfFont font) {
//        Paragraph para = new Paragraph()
//                .setMarginLeft(15)
//                .setMarginBottom(8)
//                .setFixedLeading(14)  // 缩小行高
//                .setTextAlignment(TextAlignment.LEFT);  // 两端对齐
//
//
//        processBoldText(para, text, font); // 处理加粗文本
//
//        // 如果文本中包含加号，直接在段落中显示加号
//        if (text.contains("+")) {
//            Text plusText = new Text(" ").setFont(font);  // 加号文本
//            para.add(plusText);  // 将加号添加到段落
//        }else if (text.startsWith("* ")) { // 如果以 * 开头，去掉星号和空格
//            text = text.substring(2); // 删除星号和空格
//        }
//        container.add(para);
//    }
//
//    private void processSubItem(Div container, String text, PdfFont font) {
//        Paragraph para = new Paragraph()
//                .setMarginLeft(15)  // 二级缩进
//                .setMarginBottom(6)
//                .setFixedLeading(14)  // 缩小行高
//                .setTextAlignment(TextAlignment.LEFT);  // 两端对齐
//
//        processBoldText(para, text, font); // 处理加粗文本
//
//        // 处理加号（+）符号
//        if (text.contains("+")) {
//            Text plusText = new Text(" ").setFont(font);  // 加号文本
//            para.add(plusText);  // 将加号添加到段落
//        }else if (text.startsWith("* ")) { // 如果以 * 开头，去掉星号和空格
//            text = text.substring(2); // 删除星号和空格
//        }
//
//        container.add(para);
//    }
//
//    // 新增的辅助方法：解析加粗文本
//    private void processBoldText(Paragraph para, String text, PdfFont font) {
//        // 按 ** 拆分文本
//        String[] parts = text.split("\\*\\*");
//        boolean isBold = false;
//        for (String part : parts) {
//            if (!part.isEmpty()) {
//                Text segment = new Text(part).setFont(font);
//                if (isBold) {
//                    segment.setBold(); // 将加粗文本应用到对应部分
//                }
//                para.add(segment);
//            }
//            isBold = !isBold;  // 每次切换加粗状态
//        }
//    }
//
//    private String extractName(String line) {
//        return line.replaceAll("\\*", "").trim();
//    }


    // 添加个人照片
    private static void addPersonalPhoto(Document document, PdfDocument pdf, String photoPath) throws IOException {
        // 加载图片
        Image image = new Image(ImageDataFactory.create(photoPath));
        // 压缩并固定大小为100x100（保持宽高比，避免变形）
        image.scaleToFit(100, 100);

        // 计算位置：页面右侧，与个人信息对齐（假设个人信息在页面顶部）
        float pageWidth = pdf.getDefaultPageSize().getWidth();
        float x = pageWidth - image.getImageScaledWidth() - 40; // 右侧留空40单位
        float y = pdf.getDefaultPageSize().getHeight() - 170;     // 顶部向下50单位（根据实际内容调整）

        // 使用绝对定位将图片固定在指定位置
        image.setFixedPosition(x, y);

        // 添加到文档（确保此代码在生成个人信息后调用）
        document.add(image);
    }


    /**
     * 简历上传文件接口(公众号)
     *
     * @param file
     * @param request
     * @throws IOException
     * @throws java.io.IOException
     */
    @PostMapping("/file/upload")
    public ResponseEntity<Map<String, Object>> handleFileUpload(@RequestParam("file") MultipartFile file, @RequestParam("openid") String openid,  HttpServletRequest request) throws IOException, java.io.IOException {
        if (file.isEmpty()) {
            return createErrorResponse(400, "文件为空");
        }

        // 获取文件名
        String originalFile = file.getOriginalFilename();

        // 获取当前日期，用于创建文件夹
        LocalDate currentDate = LocalDate.now();
        String dateFolder = currentDate.toString(); // 格式化为 yyyy-MM-dd

        // 构建文件的目标路径，例如: uploads/2024-12-13/文件名
        String targetFolder = uploadResume + "/" + dateFolder;
        File dateDirectory = new File(targetFolder);

        // 如果文件夹不存在，则创建
        if (!dateDirectory.exists()) {
            dateDirectory.mkdirs();
        }

        // 创建目标文件的路径
        String uuid = UUID.randomUUID().toString();
        String newFileName = uuid + originalFile.substring(originalFile.lastIndexOf("."));
        File targetFile = new File(dateDirectory, newFileName);
        // 获取文件扩展名
        String fileExtension = newFileName.substring(newFileName.lastIndexOf(".") + 1).toLowerCase();
        // 将文件存储到本地磁盘
        file.transferTo(targetFile);


        String domainName = "https://houtaiguanli.yanbeibao2021.com"; // 当前域名
        // 替换文件路径中的物理路径部分为域名和相对文件路径
        String fileUrl = targetFile.getPath().replace("/www/wwwroot/houtaiguanli.yanbeibao2021.com/dist", "").replaceFirst("^/", "/");
        // 结合域名生成完整的文件 URL
        String completeFileUrl = domainName + fileUrl;  // 确保文件路径之前有 "/file"
        // 将文件信息保存到数据库（假设有一个ServerFile实体和serverFileMapper用于持久化文件记录）
        WechatResume resume = new WechatResume();
        resume.setFileUid(uuid);
        resume.setOpenid(openid);
        resume.setName(originalFile);
        resume.setUrl(completeFileUrl);
        resume.setFilePath(targetFile.getPath());//该文件的绝对路径
        resume.setFileType(fileExtension);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();
        String format = formatter.format(date);
        resume.setCreationTime(format);
        resumeMapper.insert(resume);

        // 构建返回结果
        Map<String, Object> data = new HashMap<>();
        data.put("uuid", uuid); // 返回文件 UID（服务器生成的）
        data.put("fileName", originalFile); // 返回文件的原始名称
        data.put("serverName", newFileName); // 返回服务器保存的文件名
        data.put("fileType", fileExtension); // 返回服务器保存的文件类型
        data.put("url", completeFileUrl);
        data.put("filePath", targetFile.getPath());

        return createSuccessResponse(data, "文件上传成功");
    }


    /**
     * 简历上传文件接口(小程序)
     *
     * @param file
     * @param request
     * @throws IOException
     * @throws java.io.IOException
     */
    @PostMapping("/xcx/file/upload")
    public ResponseEntity<Map<String, Object>> handleFileUploadXcx(@RequestParam("file") MultipartFile file, @RequestParam("openid") String openid, @RequestParam("name") String name,  HttpServletRequest request) throws IOException, java.io.IOException {
        if (file.isEmpty()) {
            return createErrorResponse(400, "文件为空");
        }

        // 获取文件名
        String originalFile = file.getOriginalFilename();

        // 获取当前日期，用于创建文件夹
        LocalDate currentDate = LocalDate.now();
        String dateFolder = currentDate.toString(); // 格式化为 yyyy-MM-dd

        // 构建文件的目标路径，例如: uploads/2024-12-13/文件名
        String targetFolder = uploadResume + "/" + dateFolder;
        File dateDirectory = new File(targetFolder);

        // 如果文件夹不存在，则创建
        if (!dateDirectory.exists()) {
            dateDirectory.mkdirs();
        }

        // 创建目标文件的路径
        String uuid = UUID.randomUUID().toString();
        String newFileName = uuid + originalFile.substring(originalFile.lastIndexOf("."));
        File targetFile = new File(dateDirectory, newFileName);
        // 获取文件扩展名
        String fileExtension = newFileName.substring(newFileName.lastIndexOf(".") + 1).toLowerCase();
        // 将文件存储到本地磁盘
        file.transferTo(targetFile);


        String domainName = "https://houtaiguanli.yanbeibao2021.com"; // 当前域名
        // 替换文件路径中的物理路径部分为域名和相对文件路径
        String fileUrl = targetFile.getPath().replace("/www/wwwroot/houtaiguanli.yanbeibao2021.com/dist", "").replaceFirst("^/", "/");
        // 结合域名生成完整的文件 URL
        String completeFileUrl = domainName + fileUrl;  // 确保文件路径之前有 "/file"
        // 将文件信息保存到数据库（假设有一个ServerFile实体和serverFileMapper用于持久化文件记录）
        WechatResume resume = new WechatResume();
        resume.setFileUid(uuid);
        resume.setOpenid(openid);
        resume.setName(name);
        resume.setUrl(completeFileUrl);
        resume.setFilePath(targetFile.getPath());//该文件的绝对路径
        resume.setFileType(fileExtension);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();
        String format = formatter.format(date);
        resume.setCreationTime(format);
        resumeMapper.insert(resume);

        // 构建返回结果
        Map<String, Object> data = new HashMap<>();
        data.put("uuid", uuid); // 返回文件 UID（服务器生成的）
        data.put("fileName", name); // 返回文件的原始名称
        data.put("serverName", newFileName); // 返回服务器保存的文件名
        data.put("fileType", fileExtension); // 返回服务器保存的文件类型
        data.put("url", completeFileUrl);
        data.put("filePath", targetFile.getPath());

        return createSuccessResponse(data, "文件上传成功");
    }


    private ResponseEntity<Map<String, Object>> createSuccessResponse(Map<String, Object> body, String message) {
        Map<String, Object> response = new HashMap<>();
        response.put("code", 200); // 添加状态码字段
        response.put("message", message);
        response.put("data", body); // 将原始body作为data字段的一部分
        return ResponseEntity.ok(response);
    }

    private ResponseEntity<Map<String, Object>> createErrorResponse(int status, String message) {
        Map<String, Object> response = new HashMap<>();
        response.put("code", status); // 添加状态码字段
        response.put("message", message);
        response.put("status", status); // 保留原有的status字段，以防前端依赖此字段
        return ResponseEntity.status(status).body(response);
    }


    /**
     * 图片上传
     *
     * @param file
     * @param request
     * @return
     */
    @PostMapping("/image/upload")
    public ResponseEntity<Map<String, Object>> handleFileUploadPicture(@RequestParam("file") MultipartFile file, @RequestParam("openid") String openid, HttpServletRequest request) {
        if (file.isEmpty()) {
            return createErrorResponse(400, "文件为空");
        }

        // 获取域名和端口号
//        String domain = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();

        try {
            // 清理文件名以避免潜在的安全问题
            String cleanedFileName = file.getOriginalFilename().replaceAll("[^\\u4E00-\\u9FA5a-zA-Z0-9-_\\.]", "_");

            int lastDotIndex = cleanedFileName.lastIndexOf('.');
            String fileExtension = "";
            if (lastDotIndex != -1) {
                fileExtension = cleanedFileName.substring(lastDotIndex);
            }

            // 生成UUID
            String uuid = UUID.randomUUID().toString();
            // 拼接UUID和文件后缀作为最终文件名
            String finalFileName = uuid + fileExtension;

            // 确保上传目录存在
            Path uploadPath = Paths.get(savePicture);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            Path filePath = uploadPath.resolve(finalFileName);

            // 尝试保存文件到指定路径
            try (InputStream inputStream = file.getInputStream()) {
                Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
            } catch (java.io.IOException e) {
                return createErrorResponse(500, "无法存储文件: " + e.getMessage());
            }
            String domain = "https://houtaiguanli.yanbeibao2021.com";
            // 生成访问URL
            String fileDownloadUri = domain + "/file/resume/picture/" + URLEncoder.encode(finalFileName, "UTF-8");

            pictureMapper.deleteByOpenid(openid);//添加新图片，先删除原图片
            WechatPicture wechatPicture = new WechatPicture();
            wechatPicture.setUrl(fileDownloadUri);
            wechatPicture.setOpenid(openid);
            pictureMapper.insert(wechatPicture);

            Map<String, Object> data = new HashMap<>();
            data.put("url", fileDownloadUri);
            data.put("fileName", finalFileName);
            return createSuccessResponse(data, "文件上传成功");

        } catch (java.io.IOException e) {
            e.printStackTrace();
            return createErrorResponse(500, "无法存储文件. 错误: " + e.getMessage());
        }
    }
}

